AVR1636 Configurable PMSM Sensorless FOC using the XMEGA  1.0
AVR1636 - Firmware.c File Reference

PMSM Sensorless Field Oriented Control using the ATXmega16D4 Atmel Studio 6 (Version: 6.0.1996 - Service Pack 2) using AVR GCC Compiler -02 optimization Installed Packages: AVRGCC - 3.4.1.95 AVR Toolchain 8 Bit Version: 3.4.1.830 - GCC 4.6.2 Program Memory Usage : 6996 bytes 34.2 % Full Data Memory Usage : 162 bytes 7.9 % Full. More...

#include <stdint.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

Go to the source code of this file.

Defines

#define ADC_MUX_bm   0x3F
#define ADC_MUX_I   (ADC_CH_MUXPOS2_bm)
#define ADC_MUX_VBUS   (ADC_CH_MUXPOS2_bm | ADC_CH_MUXPOS1_bm)
#define ADC_MUX_X   0
#define ADC_PRESCALER   4
#define counter   variable_table[15]
#define CURRENT_SETTLING_TIME   14
#define data_watch   variable_table[2 + VARIABLE_TABLE_SIZE]
#define DEAD_TIME   (PWM_DB/PWM_PRESCALER)
#define e_a_display   variable_table[7]
#define e_d_display   variable_table[10]
#define EEPROM_TABLE_SIZE   32
#define HALF_SCALE   128
#define HEADER_SIZE   64
#define i_a_display   variable_table[2]
#define i_b_display   variable_table[3]
#define i_d_display   variable_table[8]
#define i_error_limit   variable_table[13 + VARIABLE_TABLE_SIZE]
#define i_k_scaling   variable_table[14 + VARIABLE_TABLE_SIZE]
#define i_ki   variable_table[16 + VARIABLE_TABLE_SIZE]
#define i_kp   variable_table[15 + VARIABLE_TABLE_SIZE]
#define i_limit   variable_table[11 + VARIABLE_TABLE_SIZE]
#define I_MAX   120
#define i_q_display   variable_table[9]
#define i_reg_scaling   variable_table[12 + VARIABLE_TABLE_SIZE]
#define input_cmd_display   variable_table[4 + VARIABLE_TABLE_SIZE]
#define ir_a_display   variable_table[5]
#define l_didt_a_display   variable_table[6]
#define l_phase   variable_table[31 + VARIABLE_TABLE_SIZE]
#define l_scaling   variable_table[30 + VARIABLE_TABLE_SIZE]
#define MESSAGE_SIZE   (HEADER_SIZE + VARIABLE_TABLE_SIZE + EEPROM_TABLE_SIZE +1)
#define mode   variable_table[3 + VARIABLE_TABLE_SIZE]
#define ONE_OVER_SQRT_THREE   148
#define ONE_OVER_THREE   85
#define osc_cal_adj   variable_table[1 + VARIABLE_TABLE_SIZE]
#define osc_error   variable_table[14]
#define p_error_limit   variable_table[22 + VARIABLE_TABLE_SIZE]
#define p_gravity   variable_table[26 + VARIABLE_TABLE_SIZE]
#define p_k_scaling   variable_table[23 + VARIABLE_TABLE_SIZE]
#define p_ki   variable_table[25 + VARIABLE_TABLE_SIZE]
#define p_kp   variable_table[24 + VARIABLE_TABLE_SIZE]
#define p_reg_scaling   variable_table[21 + VARIABLE_TABLE_SIZE]
#define PWM_CHANNEL_A   TCC0_CCABUF
#define PWM_CHANNEL_B   TCC0_CCBBUF
#define PWM_CHANNEL_C   TCC0_CCCBUF
#define PWM_CHANNEL_D   TCC0_CCDBUF
#define PWM_DB   24
#define PWM_HALF   127
#define PWM_MAX   256
#define PWM_PERIODS   960
#define PWM_PRESCALER   4
#define PWM_TIMER_ISR_VECTOR   TCC0_CCD_vect
#define r_phase   variable_table[29 + VARIABLE_TABLE_SIZE]
#define r_scaling   variable_table[28 + VARIABLE_TABLE_SIZE]
#define RXD_PIN   PIN2_bm
#define RXD_PIN_0   0
#define RXD_PIN_1   RXD_PIN
#define RXD_pin_test   (PORTD_IN & RXD_PIN)
#define s_error_limit   variable_table[7 + VARIABLE_TABLE_SIZE]
#define s_k_scaling   variable_table[8 + VARIABLE_TABLE_SIZE]
#define s_ki   variable_table[10 + VARIABLE_TABLE_SIZE]
#define s_kp   variable_table[9 + VARIABLE_TABLE_SIZE]
#define s_reg_rate   variable_table[5 + VARIABLE_TABLE_SIZE]
#define s_reg_scaling   variable_table[6 + VARIABLE_TABLE_SIZE]
#define SAMPLE_1_OFFSET   (SAMPLE_HOLD_TIME)
#define SAMPLE_2_OFFSET   (TRIGGER_OFFSET + DEAD_TIME + CURRENT_SETTLING_TIME)
#define SAMPLE_HOLD_TIME   11
#define SAMPLE_WINDOW   (SAMPLE_1_OFFSET + SAMPLE_2_OFFSET)
#define speed_display   variable_table[12]
#define speed_max   variable_table[20 + VARIABLE_TABLE_SIZE]
#define speed_min   variable_table[19 + VARIABLE_TABLE_SIZE]
#define speed_scale   variable_table[18 + VARIABLE_TABLE_SIZE]
#define SQRT_THREE_OVER_TWO   222
#define TEST_PIN   PIN6_bm
#define TEST_pin_hi   PORTC_OUTSET = TEST_PIN
#define TEST_pin_lo   PORTC_OUTCLR = TEST_PIN
#define TEST_pin_out   PORTC_DIRSET |= TEST_PIN
#define TEST_pin_totem   PORTC_PIN6CTRL |= PORT_OPC_TOTEM_gc
#define theta   variable_table[13]
#define TRIGGER_OFFSET   1
#define TWO_OVER_SQRT_THREE   148
#define TWO_OVER_THREE   171
#define TXD_PIN   PIN3_bm
#define TxD_pin_0   PORTD_OUTCLR = TXD_PIN
#define TxD_pin_1   PORTD_OUTSET = TXD_PIN
#define TxD_pin_out   PORTD_DIRSET |= TXD_PIN
#define TxD_pin_totem   PORTD_PIN3CTRL |= PORT_OPC_TOTEM_gc
#define u_a_display   variable_table[4]
#define u_scaling   variable_table[27 + VARIABLE_TABLE_SIZE]
#define UART_DATA_REGISTER   USARTD0_DATA
#define UART_STATUS_RECIEVE_TEST   (USARTD0_STATUS & USART_RXCIF_bm)
#define v_a_display   variable_table[0]
#define v_b_display   variable_table[1]
#define v_bus   variable_table[11]
#define v_bus_min   variable_table[0 + VARIABLE_TABLE_SIZE]
#define v_limit   variable_table[17 + VARIABLE_TABLE_SIZE]
#define V_MAX   123
#define V_MAX_SQUARED   (V_MAX*V_MAX)
#define VARIABLE_TABLE_SIZE   16

Functions

void calibrate_current (void)
 Current Sense Calibration.
void init_adc (void)
 Initializes ADC.
void init_eventsys (void)
 Initializes Event System.
void init_interrupts (void)
 Enable interrupts.
void init_oscillator (void)
 Initializes Oscillator for 32MHz operation.
void init_pwm (void)
 Initializes Port C Timer 0 as Three Phase PWM output with Deadtime.
void init_test_pin (void)
 Initializes pin for Code testing function.
void init_uart (void)
 Initializes UART.
 ISR (PWM_TIMER_ISR_VECTOR)
 Interrupt Service Routine for FOC.
int main (void)
 Main.
void read_eeprom (void)
 Reads EEPROM values.
void read_oscillator_cal (void)
 Reads Oscillator calibration value.
void test_oscillator (void)
 Tests accuracy of Oscillator.
void write_eeprom (void)
 Writes EEPROM values.
void write_oscillator_cal (void)
 Writes Oscillator calibration value.

Variables

uint8_t adc_user_channel = 0
uint8_t adc_user_sample
uint16_t byte_timeout
int16_t comp_ki
uint8_t correction_1
uint8_t correction_2
int8_t cos_theta
uint8_t count_dir
uint8_t data_rxd
uint8_t data_toggle
uint8_t data_txd
int8_t e_a
int8_t e_alpha
int8_t e_b
int8_t e_beta
int8_t e_c
int8_t e_d
int8_t e_q
uint8_t eeprom_number
int16_t error
int8_t i_a
int8_t i_a_last
int8_t i_a_s
int8_t i_alpha
int8_t i_b
int8_t i_b_last
int8_t i_b_s
int8_t i_beta
int8_t i_c
int8_t i_c_last
int8_t i_c_s
int8_t i_d
int16_t i_d_integral
int8_t i_d_ref
int16_t i_output_max
int8_t i_q
int16_t i_q_integral
int8_t i_q_ref
uint8_t i_sample_1
uint8_t i_sample_2
uint8_t i_sample_offset
int8_t input_cmd
int8_t input_ref
int8_t ir_a
int8_t ir_b
int8_t ir_c
int8_t l_didt_a
int8_t l_didt_b
int8_t l_didt_c
uint8_t motor_off
uint16_t osc_cal
int16_t output
int16_t p_integral
int16_t p_max
int16_t p_min
int16_t p_output_max
int16_t p_output_min
const int8_t sine_table[256] PROGMEM
uint8_t pwm_1
uint8_t pwm_2
uint8_t pwm_3
uint8_t pwm_a
uint8_t pwm_a_comp
uint8_t pwm_b
uint8_t pwm_b_comp
uint8_t pwm_c
uint8_t pwm_c_comp
uint8_t pwm_counter = 0
uint8_t pwm_state
int16_t s_integral
int16_t s_output_max
int16_t s_output_min
uint8_t s_reg_count
uint8_t sample_state_1
uint8_t sample_state_2
uint8_t sample_trigger
int8_t sin_theta
int16_t speed
uint16_t table_counter = 0
uint8_t theta_90
uint16_t theta_int
int8_t u_a
int8_t u_b
int8_t u_c
int8_t v_a
int8_t v_alpha
int8_t v_b
int8_t v_beta
int8_t v_c
int8_t v_d
uint16_t v_mag_squared
int8_t v_q
uint8_t valid_byte
uint8_t variable_table [VARIABLE_TABLE_SIZE+EEPROM_TABLE_SIZE]
uint8_t window_1
uint8_t window_2

Detailed Description

PMSM Sensorless Field Oriented Control using the ATXmega16D4 Atmel Studio 6 (Version: 6.0.1996 - Service Pack 2) using AVR GCC Compiler -02 optimization Installed Packages: AVRGCC - 3.4.1.95 AVR Toolchain 8 Bit Version: 3.4.1.830 - GCC 4.6.2 Program Memory Usage : 6996 bytes 34.2 % Full Data Memory Usage : 162 bytes 7.9 % Full.

Application note:
AVR1636 Configurable PMSM Sensorless FOC using the XMEGA
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@a.nosp@m.tmel.nosp@m..com
Name:
AVR1636 - Firmware.c
Revision:
1.0
Date:
2012-11-29 (Tue, 29 Novt 2012)


Definition in file AVR1636 - Firmware.c.


Define Documentation

#define ADC_MUX_bm   0x3F

Definition at line 161 of file AVR1636 - Firmware.c.

#define ADC_MUX_I   (ADC_CH_MUXPOS2_bm)

Definition at line 168 of file AVR1636 - Firmware.c.

Referenced by init_adc(), and ISR().

#define ADC_MUX_VBUS   (ADC_CH_MUXPOS2_bm | ADC_CH_MUXPOS1_bm)

Definition at line 166 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define ADC_MUX_X   0

Definition at line 164 of file AVR1636 - Firmware.c.

#define ADC_PRESCALER   4

Definition at line 160 of file AVR1636 - Firmware.c.

#define counter   variable_table[15]

Definition at line 374 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define CURRENT_SETTLING_TIME   14

Definition at line 174 of file AVR1636 - Firmware.c.

Definition at line 381 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define DEAD_TIME   (PWM_DB/PWM_PRESCALER)

Definition at line 173 of file AVR1636 - Firmware.c.

#define e_a_display   variable_table[7]

Definition at line 361 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define e_d_display   variable_table[10]

Definition at line 366 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define EEPROM_TABLE_SIZE   32

Definition at line 192 of file AVR1636 - Firmware.c.

Referenced by ISR(), read_eeprom(), and write_eeprom().

#define HALF_SCALE   128

Definition at line 171 of file AVR1636 - Firmware.c.

Referenced by calibrate_current(), and ISR().

#define HEADER_SIZE   64

Definition at line 195 of file AVR1636 - Firmware.c.

#define i_a_display   variable_table[2]

Definition at line 355 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define i_b_display   variable_table[3]

Definition at line 356 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define i_d_display   variable_table[8]

Definition at line 363 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 395 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 396 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 398 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 397 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 392 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define I_MAX   120

Definition at line 132 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define i_q_display   variable_table[9]

Definition at line 364 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 394 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 383 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define ir_a_display   variable_table[5]

Definition at line 359 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 360 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 417 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 416 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 198 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 382 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define ONE_OVER_SQRT_THREE   148

Definition at line 184 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define ONE_OVER_THREE   85

Definition at line 182 of file AVR1636 - Firmware.c.

Definition at line 379 of file AVR1636 - Firmware.c.

Referenced by write_oscillator_cal().

#define osc_error   variable_table[14]

Definition at line 372 of file AVR1636 - Firmware.c.

Referenced by test_oscillator().

Definition at line 407 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 411 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 408 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 410 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 409 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 406 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define PWM_CHANNEL_A   TCC0_CCABUF

Definition at line 123 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define PWM_CHANNEL_B   TCC0_CCBBUF

Definition at line 124 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define PWM_CHANNEL_C   TCC0_CCCBUF

Definition at line 125 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define PWM_CHANNEL_D   TCC0_CCDBUF

Definition at line 126 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define PWM_DB   24

Definition at line 119 of file AVR1636 - Firmware.c.

Referenced by init_pwm().

#define PWM_HALF   127

Definition at line 118 of file AVR1636 - Firmware.c.

Referenced by init_pwm(), and ISR().

#define PWM_MAX   256

Definition at line 117 of file AVR1636 - Firmware.c.

Referenced by init_pwm(), and ISR().

#define PWM_PERIODS   960

Definition at line 135 of file AVR1636 - Firmware.c.

Referenced by test_oscillator().

#define PWM_PRESCALER   4

Definition at line 116 of file AVR1636 - Firmware.c.

#define PWM_TIMER_ISR_VECTOR   TCC0_CCD_vect

Definition at line 121 of file AVR1636 - Firmware.c.

Definition at line 415 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 414 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define RXD_PIN   PIN2_bm

Definition at line 147 of file AVR1636 - Firmware.c.

Referenced by test_oscillator().

#define RXD_PIN_0   0

Definition at line 149 of file AVR1636 - Firmware.c.

Referenced by test_oscillator().

#define RXD_PIN_1   RXD_PIN

Definition at line 150 of file AVR1636 - Firmware.c.

Referenced by test_oscillator().

#define RXD_pin_test   (PORTD_IN & RXD_PIN)

Definition at line 148 of file AVR1636 - Firmware.c.

Definition at line 387 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 388 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 390 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 389 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 385 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 386 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 176 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 177 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define SAMPLE_HOLD_TIME   11

Definition at line 175 of file AVR1636 - Firmware.c.

Definition at line 179 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define speed_display   variable_table[12]

Definition at line 369 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 404 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 403 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 402 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define SQRT_THREE_OVER_TWO   222

Definition at line 186 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define TEST_PIN   PIN6_bm

Definition at line 153 of file AVR1636 - Firmware.c.

#define TEST_pin_hi   PORTC_OUTSET = TEST_PIN

Definition at line 155 of file AVR1636 - Firmware.c.

Referenced by calibrate_current(), and ISR().

#define TEST_pin_lo   PORTC_OUTCLR = TEST_PIN

Definition at line 154 of file AVR1636 - Firmware.c.

Referenced by init_test_pin(), and ISR().

#define TEST_pin_out   PORTC_DIRSET |= TEST_PIN

Definition at line 156 of file AVR1636 - Firmware.c.

Referenced by init_test_pin().

#define TEST_pin_totem   PORTC_PIN6CTRL |= PORT_OPC_TOTEM_gc

Definition at line 157 of file AVR1636 - Firmware.c.

Referenced by init_test_pin().

#define theta   variable_table[13]

Definition at line 370 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define TRIGGER_OFFSET   1

Definition at line 172 of file AVR1636 - Firmware.c.

#define TWO_OVER_SQRT_THREE   148

Definition at line 185 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define TWO_OVER_THREE   171

Definition at line 183 of file AVR1636 - Firmware.c.

#define TXD_PIN   PIN3_bm

Definition at line 141 of file AVR1636 - Firmware.c.

#define TxD_pin_0   PORTD_OUTCLR = TXD_PIN

Definition at line 142 of file AVR1636 - Firmware.c.

#define TxD_pin_1   PORTD_OUTSET = TXD_PIN

Definition at line 143 of file AVR1636 - Firmware.c.

Referenced by init_uart().

#define TxD_pin_out   PORTD_DIRSET |= TXD_PIN

Definition at line 144 of file AVR1636 - Firmware.c.

Referenced by init_uart().

#define TxD_pin_totem   PORTD_PIN3CTRL |= PORT_OPC_TOTEM_gc

Definition at line 145 of file AVR1636 - Firmware.c.

#define u_a_display   variable_table[4]

Definition at line 358 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 413 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define UART_DATA_REGISTER   USARTD0_DATA

Definition at line 138 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define UART_STATUS_RECIEVE_TEST   (USARTD0_STATUS & USART_RXCIF_bm)

Definition at line 139 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define v_a_display   variable_table[0]

Definition at line 352 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define v_b_display   variable_table[1]

Definition at line 353 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define v_bus   variable_table[11]

Definition at line 368 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 377 of file AVR1636 - Firmware.c.

Referenced by ISR().

Definition at line 400 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define V_MAX   123

Definition at line 130 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define V_MAX_SQUARED   (V_MAX*V_MAX)

Definition at line 131 of file AVR1636 - Firmware.c.

Referenced by ISR().

#define VARIABLE_TABLE_SIZE   16

Definition at line 189 of file AVR1636 - Firmware.c.

Referenced by ISR(), read_eeprom(), and write_eeprom().


Function Documentation

void calibrate_current ( void  )

Current Sense Calibration.

Measures the DC offset of the current sense shunt and the resistive divider that biases the shunt voltage above ground when the current is zero. The offset value is used in all current reconstruction calculations.

Returns:
void

Definition at line 811 of file AVR1636 - Firmware.c.

References HALF_SCALE, i_sample_1, i_sample_2, i_sample_offset, pwm_counter, and TEST_pin_hi.

Referenced by main().

{
        uint8_t bit_test;
        AWEXC_OUTOVEN = 0x00;   //Make sure all PWM outputs are disabled

        while (i_sample_offset == 0)
        {
                cli();
                bit_test = pwm_counter;
                sei();          
                if (bit_test == 3)
                {
                        TEST_pin_hi;
                        cli();
                        if ((i_sample_1 > 10) && (i_sample_1 == i_sample_2))
                        {
                                i_sample_offset = HALF_SCALE - i_sample_1;
                        }
                        sei();
                }
        }
        AWEXC_OUTOVEN = 0x3F;   //Enable all PWM outputs
}
void init_adc ( void  )

Initializes ADC.

ADC is initialized in single ended mode, Left Aligned for 8 bit values Using the 1V internal reference. The conversion is triggered by the port C timer 0 channel D through the event system.

Returns:
void

Definition at line 524 of file AVR1636 - Firmware.c.

References ADC_MUX_I.

Referenced by main().

{

        // CTRLA - ADC Control Register A
        // Bit 0 – ENABLE: ADC Enable
        
        // CTRLB - ADC Control Register B
        // Bit 4 - CONVMODE: ADC Conversion Mode: 0 = unsigned mode
        // Bits 2:1 - RESOLUTION[1:0]: ADC Conversion Result Resolution
        ADCA_CTRLB = ADC_RESOLUTION1_bm;    //8 bit resolution
        
        // REFCTRL - ADC Reference Control register
        // Bits 6:4 – REFSEL[2:0]:ADC Reference Selection: 000 INT1V Internal 1.00V
        // Bit 1 – BANDGAP: Bandgap enable
        
        // PRESCALER - ADC Clock Prescaler register
        // Bits 2:0 - PRESCALER[2:0]: ADC Prescaler configuration: 001 DIV8 8
        ADCA_PRESCALER = ADC_PRESCALER_DIV32_gc;

        // CTRL - ADC Channel Control Register
        // Bit 7 - START: START Conversion on Channel
        // Bits 4:2 - GAIN[2:0]: ADC Gain Factor
        // Bit 1:0 - INPUTMODE[1:0]: ADC Input Mode: 01 SINGLEENDED
        ADCA_CH0_CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
        
        // MUXCTRL - ADC Channel MUX Control registers
        // Bits 6:3 - MUXPOS[3:0]: MUX selection on Positive ADC input
        // Bits 1:0 - MUXNEG[1:0]: MUX selection on Negative ADC input
        //current sampling
        ADCA_CH0_MUXCTRL = ADC_MUX_I;
        
        // CTRLA - ADC Control Register A
        // Bit 0 – ENABLE: ADC Enable
        ADCA_CTRLA = ADC_ENABLE_bm;
        
        // EVCTRL - ADC Event Control Register
        // Bits 5:3 - EVSEL[2:0]: event channel input select: 0 to 3
        // Bits 0 - EVACT0: ADC Event Mode
        //Enable Event trigger
        ADCA_EVCTRL |= ADC_EVACT0_bm;
        
}       
void init_eventsys ( void  )

Initializes Event System.

Configures Event System Channel 0 to trigger an ADC conversion off of Compare D Timer/Counter C0. This is used for timing ADC samples for single shunt current reconstruction. The event system signal is brought out to Port D pin 7, used in code development. This can be disabled if the pin needs to be re purposed.

Returns:
void

Definition at line 652 of file AVR1636 - Firmware.c.

Referenced by main().

{
        // CHnMUX – Event Channel n Multiplexer Register
        // 1100 1100 TCxn_CCA Capture or Compare D Timer/Counter C0 event type E
        EVSYS_CH0MUX = 0xC7;
        
        // CLKEVOUT - Clock and Event Out Register
        // Bit 5:4 - EVOUT[1:0] - Event Output Port: 
        // 10 = PD7 Event Channel 0 output on Port D pin 7
        PORTCFG_CLKEVOUT |= PORTCFG_EVOUT1_bm;
        
        PORTD_DIRSET |= PIN7_bm;
}
void init_interrupts ( void  )

Enable interrupts.

Enables the Timer 0 Port C interrupt for Capture/Compare Channel D set to the highest level. Then enables all interrupts levels.

Returns:
void

Definition at line 848 of file AVR1636 - Firmware.c.

Referenced by main().

{
        cli();
        TCC0_INTCTRLB |= (TC0_CCDINTLVL1_bm | TC0_CCDINTLVL0_bm);
        PMIC_CTRL |= (PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm);
        sei();
}
void init_oscillator ( void  )

Initializes Oscillator for 32MHz operation.

This function enables the 32MHz internal oscillator then waits for the oscillator to be ready, then switches over the system clock to 32MHz.

Returns:
void

Definition at line 434 of file AVR1636 - Firmware.c.

Referenced by main().

{
        CCP = CCP_IOREG_gc; // disable register security for oscillator update
        OSC_CTRL = OSC_RC32MEN_bm; // enable 32MHz oscillator
        while(!(OSC_STATUS & OSC_RC32MRDY_bm))
        {
                // wait for oscillator to be ready
        }
        CCP = CCP_IOREG_gc; // disable register security for clock update
        CLK_CTRL = CLK_SCLKSEL_RC32M_gc; // switch to 32MHz clock
}
void init_pwm ( void  )

Initializes Port C Timer 0 as Three Phase PWM output with Deadtime.

PWM is configured for 31.25kHz operating frequency, 8-bit resolution 32MHz / 4 prescaler / 256 = 31.25kHz Channels A,B, and C along with the AWEX for deadtime to generate three phase PWM. Channel D is used to trigger the ADC, through the event system, for single shunt current reconstruction. Edge aligned PWM is used because it requires the least amount of PWM modification for the ADC sample window.

Returns:
void

Definition at line 486 of file AVR1636 - Firmware.c.

References PWM_DB, PWM_HALF, and PWM_MAX.

Referenced by main().

{
        PORTC_DIR |= 0x3F;      // set as output

        TCC0_CTRLA = 0x03;      // Prescaler: clk/4

        //Bit 7:4 – CCxEN: Compare or Capture Enable
        //Bit 2:0 – WGMODE[2:0]: Waveform Generation Mode = 011 SINGLESLOPE
        TCC0_CTRLB = 0x03;              // Single-slope PWM
        TCC0_PER = PWM_MAX-1;           //
        TCC0_CCA = PWM_HALF;            //
        TCC0_CCB = PWM_HALF;            //
        TCC0_CCC = PWM_HALF;
        TCC0_CCD = PWM_HALF;
        
        //CTRL - Control Register
        //Bit 3:0 - DTICCxEN: Dead-Time Insertion CCx Enable
        AWEXC_CTRL = 0x07;       //Enable A. B, and C dead time 
        
        //Dead-Time Concurrent write to Low and High Side Buffer Registers
        AWEXC_DTLS = PWM_DB;     // 24 = 750ns
        AWEXC_DTHS = PWM_DB;     // 24 = 750ns
}
void init_test_pin ( void  )

Initializes pin for Code testing function.

Test pin is used on a spare pin to look at code timing using an oscilloscope. This is only for Debugging and benchmarking code TEST_pin_hi; and TEST_pin_lo; are inserted in code to set the pin high and low.

Returns:
void

Definition at line 461 of file AVR1636 - Firmware.c.

References TEST_pin_lo, TEST_pin_out, and TEST_pin_totem.

Referenced by main().

void init_uart ( void  )

Initializes UART.

The UART is set up for bi directional 115,200 baud to match the maximum standard COM port frequency. The UART is polled in the PWM ISR that makes up the FOC control loop. THe UARt is used for communication to the PC based Atmel Motor Control Configuration Utility.

Returns:
void

Definition at line 581 of file AVR1636 - Firmware.c.

References TxD_pin_1, and TxD_pin_out.

Referenced by main().

{
        uint16_t bsel = 1047;
        uint8_t bscale = 10;
        // USART initialization should use the following sequence:
        // 1. Set the TxD pin value high, and optionally the XCK pin low.
        // 2. Set the TxD and optionally the XCK pin as output.
        // 3. Set the baud rate and frame format.
        // 4. Set mode of operation (enables XCK pin output in synchronous mode).
        // 5. Enable the Transmitter or the Receiver depending on the usage.

        TxD_pin_1;
        TxD_pin_out;

        // DATA - USART I/O Data Register
        // USARTD0_DATA
        
        // 115200 @ 32Mhz as calculated from ProtoTalk Calc
//      USARTD0_BAUDCTRLA = (uint8_t) bsel;
        USARTD0_BAUDCTRLA = (0xFF & bsel);
        USARTD0_BAUDCTRLB = (bscale << 4) | (bsel >> 8);
        
        // STATUS - USART Status Register 
        // USART_RXCIF_bm  0x80  /* Receive Interrupt Flag bit mask. */
        // USART_TXCIF_bm  0x40  /* Transmit Interrupt Flag bit mask. */
        // USARTD0_STATUS

        // BAUDCTRLA - USART Baud Rate Register
        // Bit 7:0 - BSEL[7:0]: USART Baud Rate Register
//      USARTD0_BAUDCTRLA = 138;    //For 115200 Baud, 32MHz clock, BSCALE = 10 
        
        // BAUDCTRLB - USART Baud Rate Register
        // Bit 7:4 - BSCALE[3:0]: USART Baud Rate Scale factor
        // Bit 3:0 - BSEL[11:8]: USART Baud Rate Register
//      USARTD0_BAUDCTRLB = 
//                      ( USART_BSCALE3_bm | USART_BSCALE2_bm | USART_BSCALE0_bm);
        
        // CTRLA – USART Control Register A
        // Interrupt Level - Unused
        USARTD0_CTRLA = 0;
        
        // CTRLC - USART Control Register C
        // Bits 7:6 - CMODE[1:0]: USART Communication Mode: 00 = Asynchronous USART
        // Bit 2:0 - CHSIZE[2:0]: Character Size: 011 = 8BIT, 8-bit
        USARTD0_CTRLC = USART_CHSIZE_8BIT_gc;
        
        // CTRLB - USART Control Register B
        // Bit 4 - RXEN: Receiver Enable
        // USART_RXEN_bm  0x10  /* Receiver Enable bit mask. */
        // Bit 3 - TXEN: Transmitter Enable
        // USART_TXEN_bm  0x08  /* Transmitter Enable bit mask. */
        USARTD0_CTRLB = (USART_RXEN_bm | USART_TXEN_bm);
        
}

Interrupt Service Routine for FOC.

This is the main control loop for all Field Oriented Control functions and communication with the Motor Control Configuration Utility.

Returns:
void

Definition at line 868 of file AVR1636 - Firmware.c.

References ADC_MUX_I, ADC_MUX_VBUS, adc_user_channel, adc_user_sample, byte_timeout, comp_ki, correction_1, correction_2, cos_theta, count_dir, counter, data_rxd, data_toggle, data_txd, data_watch, e_a, e_a_display, e_alpha, e_b, e_beta, e_c, e_d, e_d_display, e_q, eeprom_number, EEPROM_TABLE_SIZE, error, HALF_SCALE, i_a, i_a_display, i_a_last, i_a_s, i_alpha, i_b, i_b_display, i_b_last, i_b_s, i_beta, i_c, i_c_last, i_c_s, i_d, i_d_display, i_d_integral, i_d_ref, i_error_limit, i_k_scaling, i_ki, i_kp, i_limit, I_MAX, i_output_max, i_q, i_q_display, i_q_integral, i_q_ref, i_reg_scaling, i_sample_1, i_sample_2, i_sample_offset, input_cmd, input_cmd_display, input_ref, ir_a, ir_a_display, ir_b, ir_c, l_didt_a, l_didt_a_display, l_didt_b, l_didt_c, l_phase, l_scaling, MESSAGE_SIZE, mode, motor_off, ONE_OVER_SQRT_THREE, output, p_error_limit, p_gravity, p_integral, p_k_scaling, p_ki, p_kp, p_max, p_min, p_output_max, p_output_min, p_reg_scaling, pwm_1, pwm_2, pwm_3, pwm_a, pwm_a_comp, pwm_b, pwm_b_comp, pwm_c, pwm_c_comp, PWM_CHANNEL_A, PWM_CHANNEL_B, PWM_CHANNEL_C, PWM_CHANNEL_D, pwm_counter, PWM_HALF, PWM_MAX, pwm_state, r_phase, r_scaling, s_error_limit, s_integral, s_k_scaling, s_ki, s_kp, s_output_max, s_reg_count, s_reg_rate, s_reg_scaling, SAMPLE_1_OFFSET, SAMPLE_2_OFFSET, sample_state_1, sample_state_2, sample_trigger, SAMPLE_WINDOW, sin_theta, speed, speed_display, speed_max, speed_min, speed_scale, SQRT_THREE_OVER_TWO, table_counter, test_oscillator(), TEST_pin_hi, TEST_pin_lo, theta, theta_90, theta_int, TWO_OVER_SQRT_THREE, u_a, u_a_display, u_b, u_c, u_scaling, UART_DATA_REGISTER, UART_STATUS_RECIEVE_TEST, v_a, v_a_display, v_alpha, v_b, v_b_display, v_beta, v_bus, v_bus_min, v_c, v_d, v_limit, v_mag_squared, V_MAX, V_MAX_SQUARED, v_q, valid_byte, variable_table, VARIABLE_TABLE_SIZE, window_1, window_2, write_eeprom(), and write_oscillator_cal().

{
//TEST_pin_hi;

        // Motor Off function for updating EEPROM
        if (v_bus < v_bus_min) 
        {
                input_ref = 0;
        }
        else
        {
                input_ref = input_cmd;
        }

        if (motor_off > 0)
        {
                motor_off |= 2; //Motor PWM at 50%
                pwm_a_comp = PWM_HALF;
                pwm_b_comp = PWM_HALF;
                pwm_c_comp = PWM_HALF;
                sample_trigger = PWM_HALF;
        }
        
        // Clamp on Sample Trigger
        
        if (sample_trigger >= PWM_MAX)
        {
                sample_trigger = PWM_MAX -1;
        }
        if (sample_trigger == 0)
        {
                sample_trigger = 1;
        }
        
        
        // Three Phase PWM and Sample Trigger Update
        
        PWM_CHANNEL_A = PWM_MAX - pwm_a_comp;             //Duty cycle
        PWM_CHANNEL_B = PWM_MAX - pwm_b_comp;             //Duty cycle
        PWM_CHANNEL_C = PWM_MAX - pwm_c_comp;             //Duty cycle
        PWM_CHANNEL_D = PWM_MAX - sample_trigger;         //Duty cycle
        
        
        // Update EEPROM 
        
        // Write EEPROM function here. Non-reentrant so must disable interrupts
        // bit 0 = motor off command, bit 1 = motor turned off,
        // bit 2 = transfer variables back to EEPROM, bit 3 = Cal Oscillator
        if (motor_off == 7)
        {
                write_eeprom();
        }
        
        
        // Test Oscillator
        
        // bit 0 = motor off command, bit 1 = motor turned off,
        // bit 2 = transfer variables back to EEPROM bit 3 = Cal Oscillator
        if (motor_off == 11)
        {
                write_oscillator_cal();
                test_oscillator();
        }
        

        // PWM Counter Update
        
        pwm_counter++;
        if (pwm_counter > 3)
        {
                pwm_counter = 0;
        }
        
        
        // Serial Communications Update
        
        if (pwm_counter == 0)
        {
                if (data_toggle)
                {
                        if (table_counter < (VARIABLE_TABLE_SIZE + EEPROM_TABLE_SIZE))
                        {
                                data_txd = variable_table[table_counter];
                        }
                        else
                        {
                                if (table_counter == (VARIABLE_TABLE_SIZE + EEPROM_TABLE_SIZE))
                                {
                                        data_txd = 0;     //0 at end of data
                                }
                                else
                                {
                                        data_txd = 255;   //The rest of the data is 255s
                                }
                                
                        }
                        table_counter++;
                        if (table_counter > MESSAGE_SIZE)
                        {
                                table_counter = 0;
                                data_txd = 0;         //0 at beginning of data
                        }
                        UART_DATA_REGISTER = data_txd;
                        data_toggle = 0;
                }
                else
                {
                        
                        if (count_dir == 0)
                        {
                                counter++;
                                if (counter>254)
                                {
                                        count_dir = 1;
                                }
                        }
                        else
                        {
                                counter--;
                                if (counter<1)
                                {
                                        count_dir = 0;
                                }
                        }
                        
                        data_txd = variable_table[data_watch];
                        if (data_txd > 254)
                        {
                                data_txd = 254;       // Clip data
                        }
                        UART_DATA_REGISTER = data_txd;
                        data_toggle = 1;
                }
        }
        
        byte_timeout++;
        
        //      if (input_state == 1)
        {
        
                if (UART_STATUS_RECIEVE_TEST)     // Receive buffer full?
                {
                        data_rxd = UART_DATA_REGISTER;             // valid start bit
                        valid_byte++;
                }
                
                
                if ( byte_timeout >= 32500)              // 32500/15625Hz/2 = 1sec
                {
                        valid_byte=0;
                        byte_timeout=0;
                }
                
                if (valid_byte == 3)
                {
                        if (eeprom_number < EEPROM_TABLE_SIZE)
                        {
                                variable_table[eeprom_number + VARIABLE_TABLE_SIZE] = data_rxd;
                        }
                        
                        valid_byte=0;
                        if ((eeprom_number == 254)&(data_rxd == 254))
                        {
                                // Motor off command and variables ready for write
                                motor_off = 5;
                                eeprom_number = 0;
                        }
                        if ((eeprom_number == 255)&(data_rxd == 255))
                        {
                                // Motor off command and calibrate oscillator
                                motor_off = 9;
                                eeprom_number = 0;
                        }
                }
                
                if (valid_byte == 1)
                {
                        eeprom_number = data_rxd;
                        valid_byte++;
                }
        }
        
        // Limit on Scaling variables (0 to 7)
        
        speed_scale = speed_scale & 0x07;
        
        p_reg_scaling = p_reg_scaling & 0x07;
        p_k_scaling = p_k_scaling & 0x07;

        s_reg_scaling = s_reg_scaling & 0x07;
        s_k_scaling = s_k_scaling & 0x07;

        i_reg_scaling = i_reg_scaling & 0x07;
        i_k_scaling = i_k_scaling & 0x07;
        
        u_scaling = u_scaling & 0x07;
        
        r_scaling = r_scaling & 0x07;
        
        l_scaling = l_scaling & 0x07;
        
        if (v_limit > V_MAX)
        {
                v_limit = V_MAX;
        }
        if (i_limit > I_MAX)
        {
                i_limit = I_MAX;
        }
        
        
        
        // Sensorless FOC Routines (Cycles through 1 of 4 each ISR)
        
        switch (pwm_counter)
        {
                
                case 0:   //
                //      TEST_pin_hi;
                
                // Update Angle
                
                theta_int += speed;
                
                theta = (theta_int>>speed_scale) & 0xFF;
                
                // 90 Degrees = 256/360*90=64
                theta_90 = (theta+64) & 0xFF;
                
                if ((theta < 64) || (theta > 192))
                {
                        TEST_pin_hi;
                }
                else
                {
                        TEST_pin_lo;
                }
                
                
                // Sine and Cosine Lookup
                
                sin_theta = pgm_read_byte(&(sine_table[theta]));
                cos_theta = pgm_read_byte(&(sine_table[theta_90]));
                
                
                // Phase Current Updates
                
                // Phase Currents from last loop update
                i_a_last = i_a;
                i_b_last = i_b;
                i_c_last = i_c;
                
                // Phase Currents out to main loop
                i_a = i_a_s; //0.075A/count
                i_b = i_b_s;
                i_c = i_c_s;
                
                
                // Speed and Current Limit Update
                
                //Recalc limits in case they have changed from Config Utility
                p_min = (speed_min<<p_reg_scaling);
                p_max = (speed_max<<p_reg_scaling);
                
                s_output_max = (i_limit<<s_reg_scaling); // Calculated max current
                
                i_output_max = (v_limit<<i_reg_scaling);
                
                
                // Display Variables Update
                
                v_a_display = v_a + HALF_SCALE;
                v_b_display = v_b + HALF_SCALE;
                
                i_a_display = i_a_s + HALF_SCALE;
                i_b_display = i_b_s + HALF_SCALE;
                
                u_a_display = u_a + HALF_SCALE;
                ir_a_display = ir_a + HALF_SCALE;
                
                l_didt_a_display = l_didt_a + HALF_SCALE;
                e_a_display = e_a + HALF_SCALE;
                
                i_d_display = i_d + HALF_SCALE;
                i_q_display = i_q + HALF_SCALE;
                
                e_d_display = e_d + HALF_SCALE;
                
                input_cmd = input_cmd_display - HALF_SCALE;
                
                //Speed Display uses half value to fit signed number on Variable plot
                speed_display = speed + HALF_SCALE;
                
                
                // Speed Regulator
                
                if (mode != 2)
                {
                        s_integral = 0;
                }
                s_reg_count++;
                if (s_reg_count >= s_reg_rate)
                {
                        s_reg_count = 0;
                        
                        error = input_ref - speed;
                        
                        if(error>s_error_limit)
                        {
                                error=s_error_limit;
                        }
                        if(error<-s_error_limit)
                        {
                                error=-s_error_limit;
                        }
                        
                        output = (error * s_kp)>>s_k_scaling; //Kp
                        
                        comp_ki = (error * s_ki)>>s_k_scaling; // Ki
                        
                        s_integral += comp_ki;
                        
                        if (s_integral < -s_output_max)
                        {
                                s_integral = -s_output_max;
                        }
                        if (s_integral > s_output_max)
                        {
                                s_integral = s_output_max;
                        }
                        
                        output += s_integral;
                        
                        if (output < -s_output_max)
                        {
                                output = -s_output_max;
                        }
                        if (output > s_output_max)
                        {
                                output = s_output_max;
                        }
                        
                        i_d_ref = 0;
                        i_q_ref = output>>s_reg_scaling;
                }
                
                
                // ADC Sample

                adc_user_sample = ADCA_CH0_RES;
                ADCA_CH0_MUXCTRL = ADC_MUX_VBUS;
                
                
                // Sample 1 PWM correction
                
                switch (pwm_1)
                {
                        case 1:   // c (001) 1
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c + correction_1;
                        break;
                        
                        case 2:   // b (010) 2
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b + correction_1;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        case 4:    // a (100) 4
                        pwm_a_comp = pwm_a + correction_1;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        default:
                        pwm_a_comp = PWM_HALF;
                        pwm_b_comp = PWM_HALF;
                        pwm_c_comp = PWM_HALF;
                        break;
                }
                
                switch (pwm_2)
                {
                        case 1:   // c (001) 1
                        sample_trigger = pwm_c_comp + SAMPLE_1_OFFSET;
                        break;
                        
                        case 2:   // b (010) 2
                        sample_trigger =  pwm_b_comp + SAMPLE_1_OFFSET;
                        break;
                        
                        case 4:    // a (100) 4
                        sample_trigger = pwm_a_comp + SAMPLE_1_OFFSET;
                        break;
                        
                        default:
                        sample_trigger = PWM_HALF;
                        break;
                }
                
                
                //TEST_pin_lo;
                break;
                
                case 1:   //
                //TEST_pin_hi;
                
                // Back EMF Calculation
                
                // Phase voltage
                u_a = (v_a * v_bus)>>u_scaling; // 0.06V/count
                u_b = (v_b * v_bus)>>u_scaling;
                u_c = (v_c * v_bus)>>u_scaling;
                
                // r_phase is 0.00625 Ohms/count
                // 0.225 Ohms/0.00625 ohms/count = 36
                
                ir_a = (i_a * r_phase)>>r_scaling; // 0.06V/count
                ir_b = (i_b * r_phase)>>r_scaling;
                ir_c = (i_c * r_phase)>>r_scaling;

                l_didt_a = ((i_a - i_a_last) * l_phase)>>l_scaling; // 0.06V/count
                l_didt_b = ((i_b - i_b_last) * l_phase)>>l_scaling;
                l_didt_c = ((i_c - i_c_last) * l_phase)>>l_scaling;
                
                e_a = u_a - ir_a - l_didt_a;
                e_b = u_b - ir_b - l_didt_b;
                e_c = u_c - ir_c - l_didt_c;
                
                
                // Current 3 => 2 Clarke Transform
                
                i_alpha =i_a;
                i_beta=(((i_a*ONE_OVER_SQRT_THREE)/2)+i_b*TWO_OVER_SQRT_THREE)/128;
                
                
                // Current Vector Rotation - Park Transform
                
                i_d = (((i_alpha * cos_theta)) + ((i_beta * sin_theta)))/128;
                i_q = (-((i_alpha * sin_theta)) + ((i_beta * cos_theta)))/128;
                
                
                // Current Command
                
                if (mode == 0)
                {
                        i_d_ref = 0;  // Field Weakening not implemented
                        i_q_ref = 0;
                        i_d_integral = 0;
                        i_q_integral = 0;
                }
                if (mode == 1)
                {
                        i_d_ref = 0;  // Field Weakening not implemented
                        i_q_ref = input_ref;
                        if ( input_ref > i_limit)
                        {
                                i_q_ref = i_limit;
                        }
                        if ( input_ref < -i_limit)
                        {
                                i_q_ref = -i_limit;
                        }
                        if (input_ref == 0)
                        {
                                i_d_integral = 0;
                                i_q_integral = 0;
                        }
                }
                
                
                // ADC Sample - v_bus
                
                v_bus = ADCA_CH0_RES;
                ADCA_CH0_MUXCTRL = ADC_MUX_I;
                
                
                // Sample 2 PWM correction
                
                switch (pwm_3)
                {
                        case 1:   // c (001) 1
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c - correction_2;
                        break;
                        
                        case 2:   // b (010) 2
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b - correction_2;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        case 4:    // a (100) 4
                        pwm_a_comp = pwm_a - correction_2;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        default:
                        pwm_a_comp = PWM_HALF;
                        pwm_b_comp = PWM_HALF;
                        pwm_c_comp = PWM_HALF;
                        break;
                }
                
                switch (pwm_2)
                {
                        case 1:   // c (001) 1
                        sample_trigger = pwm_c_comp - SAMPLE_2_OFFSET;
                        break;
                        
                        case 2:   // b (010) 2
                        sample_trigger =  pwm_b_comp - SAMPLE_2_OFFSET;
                        break;
                        
                        case 4:    // a (100) 4
                        sample_trigger = pwm_a_comp - SAMPLE_2_OFFSET;
                        break;
                        
                        default:
                        sample_trigger = PWM_HALF;
                        break;
                }
                
                
                //TEST_pin_lo;
                break;
                
                case 2:   //
                //TEST_pin_hi;
                // Clarke Transform 3 => 2 Back EMF
                
                e_alpha =e_a;
                e_beta=(((e_a*ONE_OVER_SQRT_THREE)/2)+e_b*TWO_OVER_SQRT_THREE)/128;
                
                
                // Park Transform - Vector Rotation - Back EMF
                
                e_d = (((e_alpha * cos_theta)) + ((e_beta * sin_theta)))/128;
                e_q = (-((e_alpha * sin_theta)) + ((e_beta * cos_theta)))/128;
                
                
                // i_d regulator
                
                error = i_d_ref - i_d;
                
                if(error>i_error_limit)
                {
                        error=i_error_limit;
                }
                if(error<-i_error_limit)
                {
                        error=-i_error_limit;
                }
                
                output = (error*i_kp)>>i_k_scaling; //Kp
                
                comp_ki = (error * i_ki)>>i_k_scaling; // Ki
                
                i_d_integral += comp_ki;
                
                if (i_d_integral < -i_output_max)
                {
                        i_d_integral = -i_output_max;
                }
                if (i_d_integral > i_output_max)
                {
                        i_d_integral = i_output_max;
                }
                
                output += i_d_integral;
                
                if (output < -i_output_max)
                {
                        output = -i_output_max;
                }
                if (output > i_output_max)
                {
                        output = i_output_max;
                }
                
                v_d = output>>i_reg_scaling;
                
                
                // i_q regulator
                
                error = i_q_ref - i_q;
                
                if(error>i_error_limit)
                {
                        error=i_error_limit;
                }
                if(error<-i_error_limit)
                {
                        error=-i_error_limit;
                }
                
                output = (error * i_kp)>>i_k_scaling; //Kp
                
                comp_ki = (error * i_ki)>>i_k_scaling; // Ki
                
                i_q_integral += comp_ki;
                
                if (i_q_integral < -i_output_max)
                {
                        i_q_integral = -i_output_max;
                }
                if (i_q_integral > i_output_max)
                {
                        i_q_integral = i_output_max;
                }
                
                output += i_q_integral;
                
                if (output < -i_output_max)
                {
                        output = -i_output_max;
                }
                if (output > i_output_max)
                {
                        output = i_output_max;
                }
                
                v_q = output>>i_reg_scaling;
                
                
                // Voltage Command
                
                
                if (mode == 0)
                {
                        v_d = 0;
                        v_q = input_ref;
                        if ( input_ref > v_limit)
                        {
                                v_q = v_limit;
                        }
                        if ( input_ref < -v_limit)
                        {
                                v_q = -v_limit;
                        }
                }
                
                
                // Voltage Clamp
                
                v_mag_squared = (v_d * v_d) + (v_q * v_q);
                
                // Test for outside the unit circle
                // if true put in voltage mode
                if (v_mag_squared > V_MAX_SQUARED)
                {
                        v_d = 0;
                        if (v_q > 0)
                        {
                                v_q = v_limit;
                        }
                        else
                        {
                                v_q = -v_limit;
                        }
                }
                
                
                // ADC Sample
                
                i_sample_1 = ADCA_CH0_RES + i_sample_offset;
                ADCA_CH0_MUXCTRL = ADC_MUX_I;
                
                // Current 1 Sample Calculations
                
                switch (sample_state_1)
                {
                        case 1:   // V(001) = I_c
                        i_c_s = i_sample_1 - HALF_SCALE;
                        break;
                        
                        case 2:   // V(010) = I_b
                        i_b_s = i_sample_1 - HALF_SCALE;
                        break;
                        
                        case 3:   // V(011) = -I_a
                        i_a_s = HALF_SCALE - i_sample_1;
                        break;
                        
                        case 4:   // V(100) = I_a
                        i_a_s = i_sample_1 - HALF_SCALE;
                        break;
                        
                        case 5:   // V(101) = -I_b
                        i_b_s = HALF_SCALE - i_sample_1;
                        break;
                        
                        case 6:   // V(110) = -I_c
                        i_c_s = HALF_SCALE - i_sample_1;
                        break;
                }
                
                
                // Sample 2 PWM "anti-correction"
                
                switch (pwm_3)
                {
                        case 1:   // c (001) 1
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c + correction_2;
                        break;
                        
                        case 2:   // b (010) 2
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b + correction_2;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        case 4:    // a (100) 4
                        pwm_a_comp = pwm_a + correction_2;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        default:
                        pwm_a_comp = PWM_HALF;
                        pwm_b_comp = PWM_HALF;
                        pwm_c_comp = PWM_HALF;
                        break;
                }
                
                switch (pwm_2)
                {
                        case 1:   // c (001) 1
                        sample_trigger = pwm_c_comp - SAMPLE_2_OFFSET;
                        break;
                        
                        case 2:   // b (010) 2
                        sample_trigger =  pwm_b_comp - SAMPLE_2_OFFSET;
                        break;
                        
                        case 4:    // a (100) 4
                        sample_trigger = pwm_a_comp - SAMPLE_2_OFFSET;
                        break;
                        
                        default:
                        sample_trigger = PWM_HALF;
                        break;
                }
                
                
                //TEST_pin_lo;
                break;
                
                case 3:   //
                //TEST_pin_hi;
                // Back EMF PLL
                
                if (v_q == 0)
                {
                        p_integral = 0;
                }
                
                if (v_q > 0)      // Positive speed values
                {
                        error = -e_d - p_gravity;
                        p_output_min = p_min;
                        p_output_max = p_max;
                }
                else              // Negative speed values
                {
                        error = e_d + p_gravity;
                        p_output_min = -p_max;
                        p_output_max = -p_min;
                }

                
                if(error>p_error_limit)
                {
                        error=p_error_limit;
                }
                if(error<-p_error_limit)
                {
                        error=-p_error_limit;
                }
                
                output = (error * p_kp)>>p_k_scaling; //Kp
                
                comp_ki = (error * p_ki)>>p_k_scaling; // Ki
                
                p_integral += comp_ki;
                
                if (p_integral < p_output_min)
                {
                        p_integral = p_output_min;
                }
                if (p_integral > p_output_max)
                {
                        p_integral = p_output_max;
                }
                
                output += p_integral;
                
                if (output < p_output_min)
                {
                        output = p_output_min;
                }
                if (output > p_output_max)
                {
                        output = p_output_max;
                }
                
                speed = output>>p_reg_scaling;
                
                
                // Inverse Park Transform - Vector Rotation - Voltage
                
                v_alpha = (((v_d * cos_theta)) - ((v_q * sin_theta)))/128;
                v_beta = (((v_d * sin_theta)) + ((v_q * cos_theta)))/128;
                
                
                // Inverse Clarke Transform - 2 => 3 - Voltage
                
                v_a = v_alpha;
                v_b = (-(v_alpha*128)+((v_beta*SQRT_THREE_OVER_TWO)))/256;
                v_c = (-(v_alpha*128)-((v_beta*SQRT_THREE_OVER_TWO)))/256;
                
                
                // ADC Sample
                
                i_sample_2 = ADCA_CH0_RES + i_sample_offset;
                ADCA_CH0_MUXCTRL = adc_user_channel;

                // Current 2 Sample Calculation
                
                switch (sample_state_2)
                {
                        case 1:   // V(001) = I_c
                        i_c_s = i_sample_2 - HALF_SCALE;
                        break;
                        
                        case 2:   // V(010) = I_b
                        i_b_s = i_sample_2 - HALF_SCALE;
                        break;
                        
                        case 3:   // V(011) = -I_a
                        i_a_s = HALF_SCALE - i_sample_2;
                        break;
                        
                        case 4:   // V(100) = I_a
                        i_a_s = i_sample_2 - HALF_SCALE;
                        break;
                        
                        case 5:   // V(101) = -I_b
                        i_b_s = HALF_SCALE - i_sample_2;
                        break;
                        
                        case 6:   // V(110) = -I_c
                        i_c_s = HALF_SCALE - i_sample_2;
                        break;
                }
                
                
                // Three phase current calculation
                
                if ((sample_state_1 != 3) && (sample_state_1 != 4))
                {
                        if ((sample_state_2 != 3) && (sample_state_2 != 4))
                        {
                                i_a_s = -(i_c_s + i_b_s);
                        }
                }
                if ((sample_state_1 != 2) && (sample_state_1 != 5))
                {
                        if ((sample_state_2 != 2) && (sample_state_2 != 5))
                        {
                                i_b_s = -(i_c_s + i_a_s);
                        }
                }
                if ((sample_state_1 != 1) && (sample_state_1 != 6))
                {
                        if ((sample_state_2 != 1) && (sample_state_2 != 6))
                        {
                                i_c_s = -(i_a_s + i_b_s);
                        }
                }
                
                
                // PWM State and Sample windows Calculation
                
                pwm_a = PWM_HALF + v_a;
                pwm_b = PWM_HALF + v_b;
                pwm_c = PWM_HALF + v_c;
                
                pwm_state = 0;
                if (pwm_a >= PWM_HALF)
                {
                        pwm_state = 4;
                }
                if (pwm_b >= PWM_HALF)
                {
                        pwm_state |= 2;
                }
                if (pwm_c >= PWM_HALF)
                {
                        pwm_state |= 1;
                }
                
                switch (pwm_state)
                {
                        case 1:   // V(001)
                        sample_state_1 = 1;       // V(001) = I_c
                        if (pwm_a < pwm_b)
                        {
                                sample_state_2 = 3;       // V(011) = -I_a
                                window_1 = pwm_c - pwm_b;
                                window_2 = pwm_b - pwm_a;
                                pwm_1 = 1;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 2;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 4;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        else
                        {
                                sample_state_2 = 5;       // V(101) = -I_b
                                window_1 = pwm_c - pwm_a;
                                window_2 = pwm_a - pwm_b;
                                pwm_1 = 1;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 4;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 2;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        break;
                        case 2:   // V(010)
                        sample_state_1 = 2;       // V(010) = I_b
                        pwm_1 = 2;        // first sample 4 = A, 2 = B, 1 = C
                        if (pwm_c < pwm_a)
                        {
                                sample_state_2 = 6;       // V(110) = -I_c
                                window_1 = pwm_b - pwm_a;
                                window_2 = pwm_a - pwm_c;
                                pwm_1 = 2;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 4;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 1;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        else
                        {
                                sample_state_2 = 3;       // V(011) = -I_a
                                window_1 = pwm_b - pwm_c;
                                window_2 = pwm_c - pwm_a;
                                pwm_1 = 2;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 1;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 4;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        break;
                        
                        case 4:   // V(100)
                        sample_state_1 = 4;       // V(100) = I_a
                        if (pwm_b < pwm_c)
                        {
                                sample_state_2 = 5;       // V(101) = -I_b
                                window_1 = pwm_a - pwm_c;
                                window_2 = pwm_c - pwm_b;
                                pwm_1 = 4;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 1;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 2;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        else
                        {
                                sample_state_2 = 6;       // V(110) = -I_c
                                window_1 = pwm_a - pwm_b;
                                window_2 = pwm_b - pwm_c;
                                pwm_1 = 4;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 2;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 1;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        break;
                        
                        case 6:   // V(110)
                        sample_state_2 = 6;       // V(110) = -I_c
                        if (pwm_a > pwm_b)
                        {
                                sample_state_1 = 4;       // V(100) = I_a
                                window_1 = pwm_a - pwm_b;
                                window_2 = pwm_b - pwm_c;
                                pwm_1 = 4;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 2;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 1;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        else
                        {
                                sample_state_1 = 2;       // V(010) = I_b
                                window_1 = pwm_b - pwm_a;
                                window_2 = pwm_a - pwm_c;
                                pwm_1 = 2;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 4;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 1;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        break;
                        
                        case 5:   // V(101)
                        sample_state_2 = 5;       // V(101) = -I_b
                        if (pwm_c > pwm_a)
                        {
                                sample_state_1 = 1;       // V(001) = I_c
                                window_1 = pwm_c - pwm_a;
                                window_2 = pwm_a - pwm_b;
                                pwm_1 = 1;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 4;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 2;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        else
                        {
                                sample_state_1 = 4;       // V(100) = I_a
                                window_1 = pwm_a - pwm_c;
                                window_2 = pwm_c - pwm_b;
                                pwm_1 = 4;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 1;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 2;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        break;
                        
                        case 3:   // V(011)
                        sample_state_2 = 3;       // V(011) = -I_a
                        if (pwm_b > pwm_c)
                        {
                                sample_state_1 = 2;       // V(010) = I_b
                                window_1 = pwm_b - pwm_c;
                                window_2 = pwm_c - pwm_a;
                                pwm_1 = 2;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 1;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 4;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        else
                        {
                                sample_state_1 = 1;       // V(001) = I_c
                                window_1 = pwm_c - pwm_b;
                                window_2 = pwm_b - pwm_a;
                                pwm_1 = 1;        // first sample 4 = A, 2 = B, 1 = C
                                pwm_2 = 2;        // second sample 4 = A, 2 = B, 1 = C
                                pwm_3 = 4;        // second sample 4 = A, 2 = B, 1 = C
                        }
                        break;
                        
                        default:
                        
                        break;
                }
                
                correction_1 = 0;
                correction_2 = 0;
                if (window_1 < SAMPLE_WINDOW)
                {
                        correction_1 = SAMPLE_WINDOW - window_1;
                }
                if (window_2 < SAMPLE_WINDOW)
                {
                        correction_2 = SAMPLE_WINDOW - window_2;
                }
                
                
                // Sample 1 PWM "anti-correction"
                
                switch (pwm_1)
                {
                        case 1:   // c (001) 1
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c - correction_1;
                        break;
                        
                        case 2:   // b (010) 2
                        pwm_a_comp = pwm_a;
                        pwm_b_comp = pwm_b - correction_1;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        case 4:    // a (100) 4
                        pwm_a_comp = pwm_a - correction_1;
                        pwm_b_comp = pwm_b;
                        pwm_c_comp = pwm_c;
                        break;
                        
                        default:
                        pwm_a_comp = PWM_HALF;
                        pwm_b_comp = PWM_HALF;
                        pwm_c_comp = PWM_HALF;
                        break;
                }
                
                
                switch (pwm_2)
                {
                        case 1:   // c (001) 1
                        sample_trigger = pwm_c_comp + SAMPLE_1_OFFSET;
                        break;
                        
                        case 2:   // b (010) 2
                        sample_trigger =  pwm_b_comp + SAMPLE_1_OFFSET;
                        break;
                        
                        case 4:    // a (100) 4
                        sample_trigger = pwm_a_comp + SAMPLE_1_OFFSET;
                        break;
                        
                        default:
                        sample_trigger = PWM_HALF;
                        break;
                }
                
                break;
                
                default:
                
                break;
                
        }
        
        //      TEST_pin_lo;
        
}
int main ( void  )

Main.

Performs all installation function calls then sits waiting for ISR

Returns:
void

Definition at line 2077 of file AVR1636 - Firmware.c.

References calibrate_current(), init_adc(), init_eventsys(), init_interrupts(), init_oscillator(), init_pwm(), init_test_pin(), init_uart(), read_eeprom(), read_oscillator_cal(), and write_oscillator_cal().

{
        init_oscillator();
        init_test_pin();
        init_pwm();
        init_adc();
        init_uart();
        init_eventsys();
        init_interrupts();
        read_eeprom();      // Read the EEPROM contents once on power up
        calibrate_current();
        read_oscillator_cal();
        write_oscillator_cal();
        
        while(1)
        {
                //Application code here
        }
}
void read_eeprom ( void  )

Reads EEPROM values.

EEPROM values are used for configuration of motor parameters These values are configured and updated from the PC based Motor Control Configuration Utility

Returns:
void

Definition at line 679 of file AVR1636 - Firmware.c.

References EEPROM_TABLE_SIZE, table_counter, variable_table, and VARIABLE_TABLE_SIZE.

Referenced by main().

{
        cli();
        table_counter = 0;
        while (table_counter < EEPROM_TABLE_SIZE)
        { 
                variable_table[VARIABLE_TABLE_SIZE + table_counter] = 
                                eeprom_read_byte((uint8_t*)(table_counter));
                table_counter++;
        }
        table_counter = 0;
        sei();
}
void read_oscillator_cal ( void  )

Reads Oscillator calibration value.

Reads in factory calibration value for 32Mhz oscillator and stores in RAM.

Returns:
void

Definition at line 734 of file AVR1636 - Firmware.c.

References osc_cal.

Referenced by main().

{
        osc_cal = ((DFLLRC32M_CALB & 0x1F)<<8) + DFLLRC32M_CALA;
}
void test_oscillator ( void  )

Tests accuracy of Oscillator.

Compares to USB to UART bridge oscillator to internal oscillator PC sends a 0 byte at 300 baud, for a 30ms period count the number of PWM periods. 30ms/31.25us = 960 periods

Returns:
void

Definition at line 774 of file AVR1636 - Firmware.c.

References motor_off, osc_error, PWM_PERIODS, RXD_PIN, RXD_PIN_0, RXD_PIN_1, and table_counter.

Referenced by ISR().

{
        uint16_t osc_pwm_periods;
        cli();
        osc_pwm_periods = 0;
        while ((PORTD_IN & RXD_PIN) == RXD_PIN_1 )
        {
                
        }
        while ((PORTD_IN & RXD_PIN) == RXD_PIN_0 )
        {
                if((TCC0_INTFLAGS & TC0_CCDIF_bm) == TC0_CCDIF_bm)
                {
                        TCC0_INTFLAGS |= TC0_CCDIF_bm;
                        osc_pwm_periods++;
                }
        }
        osc_error = 128 + osc_pwm_periods - PWM_PERIODS;
        motor_off = 0;
        table_counter = 0;
        sei();
}
void write_eeprom ( void  )

Writes EEPROM values.

EEPROM values are used for configuration of motor parameters These values are configured and updated from the PC based Motor Control Configuration Utility

Returns:
void

Definition at line 707 of file AVR1636 - Firmware.c.

References EEPROM_TABLE_SIZE, motor_off, table_counter, variable_table, and VARIABLE_TABLE_SIZE.

Referenced by ISR().

{
        cli();
        table_counter = 0;
        while (table_counter < EEPROM_TABLE_SIZE)
        {
                eeprom_write_byte ((uint8_t*)(table_counter),
                                variable_table[VARIABLE_TABLE_SIZE + table_counter]);
                table_counter++;
        }
        table_counter = 0;
        motor_off = 0;
        sei();
}
void write_oscillator_cal ( void  )

Writes Oscillator calibration value.

Writes calibration value for 32Mhz oscillator.

Returns:
void

Definition at line 751 of file AVR1636 - Firmware.c.

References osc_cal, and osc_cal_adj.

Referenced by ISR(), and main().

{
        if (osc_cal_adj < 65)
        {
                DFLLRC32M_CALB = (((osc_cal + osc_cal_adj - 32)>>8) & 0x1F);
                DFLLRC32M_CALA = ((osc_cal + osc_cal_adj - 32) & 0xFF);
        }
}

Variable Documentation

uint8_t adc_user_channel = 0

Definition at line 242 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t adc_user_sample

Definition at line 243 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint16_t byte_timeout

Definition at line 209 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t comp_ki

Definition at line 328 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t correction_1

Definition at line 232 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t correction_2

Definition at line 233 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t cos_theta

Definition at line 247 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t count_dir

Definition at line 214 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t data_rxd

Definition at line 211 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t data_toggle

Definition at line 212 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t data_txd

Definition at line 210 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_a

Definition at line 288 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_alpha

Definition at line 292 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_b

Definition at line 289 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_beta

Definition at line 293 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_c

Definition at line 290 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_d

Definition at line 295 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t e_q

Definition at line 296 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t eeprom_number

Definition at line 218 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t error

Definition at line 327 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_a

Definition at line 254 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_a_last

Definition at line 262 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_a_s

Definition at line 258 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_alpha

Definition at line 252 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_b

Definition at line 255 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_b_last

Definition at line 263 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_b_s

Definition at line 259 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_beta

Definition at line 253 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_c

Definition at line 256 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_c_last

Definition at line 264 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_c_s

Definition at line 260 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_d

Definition at line 250 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t i_d_integral

Definition at line 321 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_d_ref

Definition at line 319 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t i_output_max

Definition at line 323 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_q

Definition at line 251 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t i_q_integral

Definition at line 322 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t i_q_ref

Definition at line 320 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t i_sample_1

Definition at line 226 of file AVR1636 - Firmware.c.

Referenced by calibrate_current(), and ISR().

uint8_t i_sample_2

Definition at line 227 of file AVR1636 - Firmware.c.

Referenced by calibrate_current(), and ISR().

uint8_t i_sample_offset

Definition at line 225 of file AVR1636 - Firmware.c.

Referenced by calibrate_current(), and ISR().

int8_t input_cmd

Definition at line 337 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t input_ref

Definition at line 326 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t ir_a

Definition at line 280 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t ir_b

Definition at line 281 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t ir_c

Definition at line 282 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t l_didt_a

Definition at line 284 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t l_didt_b

Definition at line 285 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t l_didt_c

Definition at line 286 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t motor_off

Definition at line 221 of file AVR1636 - Firmware.c.

Referenced by ISR(), test_oscillator(), and write_eeprom().

uint16_t osc_cal

Definition at line 343 of file AVR1636 - Firmware.c.

Referenced by read_oscillator_cal(), and write_oscillator_cal().

int16_t output

Definition at line 329 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t p_integral

Definition at line 306 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t p_max

Definition at line 308 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t p_min

Definition at line 307 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t p_output_max

Definition at line 310 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t p_output_min

Definition at line 309 of file AVR1636 - Firmware.c.

Referenced by ISR().

const int8_t sine_table [256] PROGMEM

Definition at line 74 of file AVR1636 - Firmware.c.

uint8_t pwm_1

Definition at line 234 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_2

Definition at line 235 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_3

Definition at line 236 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_a

Definition at line 299 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_a_comp

Definition at line 237 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_b

Definition at line 300 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_b_comp

Definition at line 238 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_c

Definition at line 301 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_c_comp

Definition at line 239 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t pwm_counter = 0

Definition at line 206 of file AVR1636 - Firmware.c.

Referenced by calibrate_current(), and ISR().

uint8_t pwm_state

Definition at line 303 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t s_integral

Definition at line 314 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t s_output_max

Definition at line 316 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t s_output_min

Definition at line 315 of file AVR1636 - Firmware.c.

uint8_t s_reg_count

Definition at line 313 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t sample_state_1

Definition at line 228 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t sample_state_2

Definition at line 229 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t sample_trigger

Definition at line 302 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t sin_theta

Definition at line 246 of file AVR1636 - Firmware.c.

Referenced by ISR().

int16_t speed

Definition at line 336 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint16_t table_counter = 0

Definition at line 346 of file AVR1636 - Firmware.c.

Referenced by ISR(), read_eeprom(), test_oscillator(), and write_eeprom().

uint8_t theta_90

Definition at line 333 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint16_t theta_int

Definition at line 332 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t u_a

Definition at line 276 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t u_b

Definition at line 277 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t u_c

Definition at line 278 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_a

Definition at line 271 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_alpha

Definition at line 269 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_b

Definition at line 272 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_beta

Definition at line 270 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_c

Definition at line 273 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_d

Definition at line 267 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint16_t v_mag_squared

Definition at line 340 of file AVR1636 - Firmware.c.

Referenced by ISR().

int8_t v_q

Definition at line 268 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t valid_byte

Definition at line 217 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t window_1

Definition at line 230 of file AVR1636 - Firmware.c.

Referenced by ISR().

uint8_t window_2

Definition at line 231 of file AVR1636 - Firmware.c.

Referenced by ISR().